/**
 * Copyright(c) 2014 Xunton Solutions
 *
 * History:
 *   15-8-31 下午6:38 Created by dwzhang
 */
package com.jade.bss.service.push.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.jade.bss.service.push.*;
import com.jade.framework.base.util.DataUtils;
import com.jade.framework.base.util.Parameters;
import com.tencent.xinge.Message;
import com.tencent.xinge.MessageIOS;
import com.tencent.xinge.XingeApp;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;

/**
 * 采用信鸽的推送服务。
 *
 * @author <a href="mailto:dwzhang@xunton.com">dwzhang</a> 
 * @version 1.0 15-8-31 下午6:38
 */
public class XingePushService
        extends AbstractPushService
{
    public PushResult pushNotification(String appCode, String platform, String audienceType, String[] audiences,
                                       boolean isAnd,
                                       String title, String notification, Parameters serviceParams,
                                       Parameters pushParams)
            throws PushException
    {
        return push("notification", appCode, platform, audienceType, audiences, isAnd, title, notification,
                serviceParams, pushParams);
    }

    public PushResult pushMessage(String appCode, String platform, String audienceType, String[] audiences,
                                  boolean isAnd,
                                  String title, String notification, Parameters serviceParams, Parameters pushParams)
            throws PushException
    {
        return push("message", appCode, platform, audienceType, audiences, isAnd, title, notification, serviceParams,
                pushParams);
    }

    protected PushResult push(String type, String appCode, String platform, String audienceType, String[] audiences,
                              boolean isAnd,
                              String title, String notification, Parameters serviceParams, Parameters pushParams)
            throws PushException
    {
        PushApp app = appConfig.getApp(appCode);
        XingeApp push = new XingeApp(DataUtils.getLong(app.getApp(), 0), app.getSecret());
        String tagsOP = isAnd ? "AND" : "OR";
        Map<String, Object> custom = new HashMap<String, Object>();
        serviceParams.putAll(custom);

        JSONObject result;
        if (StringUtils.equalsIgnoreCase(platform, PushConstants.PLATFORM_ANDROID)) {
            result = sendAndoridPush(type, push, audienceType, audiences, tagsOP, title, notification, custom,
                    pushParams);
            log.info("Send push message to Xinge platoform for Android: " + result.toString());
        }
        else if (StringUtils.equalsIgnoreCase(platform, PushConstants.PLATFORM_IOS)) {
            result = sendIOSPush(type, push, audienceType, audiences, tagsOP, notification, custom, pushParams);
            log.info("Send push message to Xinge platoform for IOS: " + result.toString());
        }
        else {
            result = sendAndoridPush(type, push, audienceType, audiences, tagsOP, title, notification, custom,
                    pushParams);
            log.info("Send push message to Xinge platoform for Android: " + result.toString());
            result = sendIOSPush(type, push, audienceType, audiences, tagsOP, notification, custom, pushParams);
            log.info("Send push message to Xinge platoform for IOS: " + result.toString());
        }
        PushResult pr = new PushResult(result.getInt("ret_code") == 0, 0, 0);
        pr.setErrMsg(result.getString("err_msg"));
        return pr;
    }

    protected JSONObject sendAndoridPush(String type, XingeApp app, String audienceType, String[] audiences,
                                         String tagsOP,
                                         String title, String notification, Map<String, Object> custom,
                                         Parameters pushParams)
    {
        Message message = new Message();
        message.setContent(notification);
        message.setCustom(custom);
        message.setTitle(title);
        if (StringUtils.equalsIgnoreCase(type, "message")) {
            message.setType(Message.TYPE_MESSAGE);
        }
        else {
            message.setType(Message.TYPE_NOTIFICATION);
        }
        JSONObject result;
        if (StringUtils.equalsIgnoreCase(audienceType, PushConstants.AUDIENCE_ACCOUNT) || StringUtils.equalsIgnoreCase(
                audienceType, PushConstants.AUDIENCE_ID)) {
            List<String> accounts = new ArrayList<String>();
            CollectionUtils.addAll(accounts, audiences);
            result = app.pushAccountList(0, accounts, message);
        }
        else if (StringUtils.equalsIgnoreCase(audienceType, PushConstants.AUDIENCE_TAG)) {
            List<String> tags = new ArrayList<String>();
            CollectionUtils.addAll(tags, audiences);
            result = app.pushTags(0, tags, tagsOP, message);
        }
        else {
            result = app.pushAllDevice(0, message);
        }
        return result;
    }

    protected JSONObject sendIOSPush(String type, XingeApp app, String audienceType, String[] audiences, String tagsOP,
                                     String notification, Map<String, Object> custom, Parameters pushParams)
    {
        boolean apnsProduction = pushParams.getBoolean("apns_production", true);
        MessageIOS message = new MessageIOS();
        message.setAlert(notification);
        message.setCustom(custom);
        int env = apnsProduction ? XingeApp.IOSENV_PROD : XingeApp.IOSENV_DEV;
        JSONObject result;
        if (StringUtils.equalsIgnoreCase(audienceType, PushConstants.AUDIENCE_ACCOUNT) || StringUtils.equalsIgnoreCase(
                audienceType, PushConstants.AUDIENCE_ID)) {
            List<String> accounts = new ArrayList<String>();
            CollectionUtils.addAll(accounts, audiences);
            result = app.pushAccountList(0, accounts, message, env);
        }
        else if (StringUtils.equalsIgnoreCase(audienceType, PushConstants.AUDIENCE_TAG)) {
            List<String> tags = new ArrayList<String>();
            CollectionUtils.addAll(tags, audiences);
            result = app.pushTags(0, tags, tagsOP, message, env);
        }
        else {
            result = app.pushAllDevice(0, message, env);
        }
        return result;
    }

    public ReceivedResult getReport(String appCode, long msgId)
            throws PushException
    {
        return null;  //To change body of implemented methods use File | Settings | File Templates.
    }
}
